package statsyslogic

import (
	"context"
	"github.com/zeromicro/go-zero/core/mr"
	"go.uber.org/zap"
	"navi-mumbai/app/rpc/model/pg/stat"
	"navi-mumbai/common/key/dbkey"
	"navi-mumbai/common/utils"
	"navi-mumbai/common/xerr"
	"strconv"
	"time"

	"navi-mumbai/app/rpc/stat/internal/svc"
	"navi-mumbai/app/rpc/stat/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateTodayLtvLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewUpdateTodayLtvLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateTodayLtvLogic {
	return &UpdateTodayLtvLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// update today ltv
func (l *UpdateTodayLtvLogic) UpdateTodayLtv(in *pb.UpdateTodayLtvReq) (*pb.UpdateTodayLtvResp, error) {
	defer utils.RecoverPanic()

	var start, end *time.Time
	if in.StartTime != "" {
		loc, _ := time.LoadLocation(dbkey.DateTimeZone)
		t, err := time.ParseInLocation(dbkey.DateTimeCNFormat, in.StartTime, loc)
		if err != nil {
			l.Logger.Errorf("err == ", zap.Error(err))
			return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, err.Error())
		}
		start = &t
	}
	if in.EndTime != "" {
		loc, _ := time.LoadLocation(dbkey.DateTimeZone)
		t, err := time.ParseInLocation(dbkey.DateTimeCNFormat, in.EndTime, loc)
		if err != nil {
			l.Logger.Errorf("err == ", zap.Error(err))
			return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, err.Error())
		}
		end = &t
	}

	var ltv stat.LifeTimeValue
	ltv.StatDay, _ = strconv.ParseInt(start.Format(dbkey.DateFormat2), 10, 64)
	var err error
	// 查询今日新用户起始uid
	var startUid, endUid int64
	startUid, err = l.svcCtx.UserAccountModel.FindFirstUid(l.ctx, start, end)
	if err != nil && err != stat.ErrNotFound {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	endUid, err = l.svcCtx.UserAccountModel.FindLastUid(l.ctx, start, end)
	if err != nil && err != stat.ErrNotFound {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}

	if startUid != 0 && endUid != 0 {
		err = mr.Finish(
			func() error {
				// 新用户
				ltv.NewUserCount, err = l.svcCtx.UserAccountModel.Count(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 活跃用户
				ltv.ActiveUserCount, err = l.svcCtx.UserLoginStatModel.CountLoginUser(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日充值新用户数
				ltv.DepositNewUserCount, err = l.svcCtx.UserDepositFlowModel.CountNewUserCount(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日新用户充值金额
				ltv.NewUserDepositAmount, err = l.svcCtx.UserDepositFlowModel.SumNewUserAmount(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日充值用户数
				ltv.DepositUserCount, err = l.svcCtx.UserDepositFlowModel.CountSuccessUser2(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日充值金额
				ltv.UserDepositAmount, err = l.svcCtx.UserDepositFlowModel.SumAmount(l.ctx, 0, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日提现新用户数
				ltv.WithdrawNewUserCount, err = l.svcCtx.UserWithdrawFlowModel.CountSuccessNewUser(l.ctx, startUid, endUid, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日新用户提现金额
				ltv.NewUserWithdrawAmount, err = l.svcCtx.UserWithdrawFlowModel.SumNewUserAmount(l.ctx, startUid, endUid, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日提现用户数
				ltv.WithdrawUserCount, err = l.svcCtx.UserWithdrawFlowModel.CountSuccessUser2(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日提现金额
				ltv.WithdrawAmount, err = l.svcCtx.UserWithdrawFlowModel.SumAmount(l.ctx, 0, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日下单新用户数
				ltv.OrderNewUserCount, err = l.svcCtx.UserGameOrderFlowModel.CountNewUserOrder(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日新用户下单金额
				ltv.NewUserOrderAmount, err = l.svcCtx.UserGameOrderFlowModel.SumNewUserOrderAmount(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日返利新用户数量
				ltv.ReturnNewUserCount, err = l.svcCtx.UserGameOrderFlowModel.CountNewUserReturn(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日新用户返利金额
				ltv.NewUserReturnAmount, err = l.svcCtx.UserGameOrderFlowModel.SumNewUserReturnAmount(l.ctx, start, end, startUid, endUid)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日下单用户数
				ltv.OrderUserCount, err = l.svcCtx.UserGameOrderFlowModel.CountUserOrder(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日用户下单金额
				ltv.OrderAmount, err = l.svcCtx.UserGameOrderFlowModel.SumUserOrderAmount(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日返利用户数量
				ltv.ReturnUserCount, err = l.svcCtx.UserGameOrderFlowModel.CountUserReturn(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
			func() error {
				// 今日用户返利金额
				ltv.ReturnAmount, err = l.svcCtx.UserGameOrderFlowModel.SumUserReturnAmount(l.ctx, start, end)
				if err != nil {
					l.Logger.Errorf("err == ", zap.Error(err))
				}
				return nil
			},
		)
		if err != nil {
			l.Logger.Errorf("err == ", zap.Error(err))
		}
	}

	_, err = l.svcCtx.LifeTimeValueModel.Insert(l.ctx, &ltv)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, xerr.NewGrpcErrCodeMsg(xerr.DbError, err.Error())
	}
	return &pb.UpdateTodayLtvResp{}, nil
}
